package com.taoz.rpc.core.spi;

import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class SpiLoader {
    private static final Map<String, Class<?>> CLASS_MAP = new ConcurrentHashMap<>();
    private static final Map<String, Object> INSTANCE_MAP = new ConcurrentHashMap<>();

    private static final String RPC_SYSTEM_SPI_DIR = "META-INF/rpc/system/";
    private static final String RPC_CUSTOM_SPI_DIR = "META-INF/rpc/custom/";

    private static final String[] SCAN_DIRS = new String[]{RPC_SYSTEM_SPI_DIR, RPC_CUSTOM_SPI_DIR};

    public static Object getInstance(String className) throws InstantiationException, IllegalAccessException {
        if (INSTANCE_MAP.get(className) == null) {
            synchronized (className.intern()) {
                if (INSTANCE_MAP.get(className) == null) {
                    log.info(className + " 准备实例化");
                    INSTANCE_MAP.put(className, CLASS_MAP.get(className).newInstance());
                }
            }
        }
        return INSTANCE_MAP.get(className);
    }

    public static void load(Class<?> interfaceClass) {
        for (String scanDir : SCAN_DIRS) {
            String scanFile = scanDir + interfaceClass.getName();
            try (InputStream inputStream = SpiLoader.class.getClassLoader().getResourceAsStream(scanFile);
                 BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
                String className;
                while ((className = reader.readLine()) != null) {
                    CLASS_MAP.put(className, Class.forName(className));
                }
            } catch (Exception e) {
                log.info("读取文件：" + scanFile + " 失败");
            }
        }
    }
}
